package com.xpec.c4.service.common;

import java.security.MessageDigest;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

public class EncryptHandler
{
	private static final String HMAC_SHA1_ALGORITHM = "HmacSHA1";
	
	
	private static final char[] digits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd',
		'e', 'f' };
	
	private static byte[] encodeData;
	private static String charSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

	static
	{
		encodeData = new byte[64];
		for (int i = 0; i < 64; i++)
		{
			byte c = (byte) charSet.charAt(i);
			encodeData[i] = c;
		}
	}
	
	public static String md5(String input){
		String result = "";
		 try {
			 MessageDigest encrypt = MessageDigest.getInstance("MD5");
			 encrypt.update(input.getBytes("UTF-8"));
			 result = hexEncode(encrypt.digest());

		 } catch (Exception e) {
			 e.printStackTrace();
		 }
		 return result;
	}
	
	
	public static String hmacSHA1BASE64(String input, String key){
		String result = "";
		 try {
			 SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(), HMAC_SHA1_ALGORITHM);
			 Mac encrypt = Mac.getInstance(HMAC_SHA1_ALGORITHM);
			 encrypt.init(signingKey);
			 encrypt.update(input.getBytes("UTF-8"));
			 result = customBase64Encode(encrypt.doFinal());

		 } catch (Exception e) {
			 e.printStackTrace();
		 }
		 return result;
	}
	
	public static String sha1(String input){
		String result = "";
		 try {
			 MessageDigest encrypt = MessageDigest.getInstance("SHA-1");
			 encrypt.update(input.getBytes("UTF-8"));
			 result = hexEncode(encrypt.digest());

		 } catch (Exception e) {
			 e.printStackTrace();
		 }
		 return result;
	}
	
	public static String sha1Base64(String input){
		String result = "";
		 try {
			 MessageDigest encrypt = MessageDigest.getInstance("SHA-1");
			 encrypt.update(input.getBytes("UTF-8"));
			 result = customBase64Encode(encrypt.digest());

		 } catch (Exception e) {
			 e.printStackTrace();
		 }
		 return result;
	}
	
	public static String sha1(String input, int number){
		String result = "";
		 try {
			 MessageDigest encrypt = MessageDigest.getInstance("SHA-1");
			 encrypt.update(input.getBytes("UTF-8"));
			 byte[] inputDigest = encrypt.digest();
			 StringBuilder tempBuf = new StringBuilder();
			 appendHexEncode(tempBuf, inputDigest);
			 tempBuf.append(String.valueOf(number));
			 String temp = tempBuf.toString();
			 
			 encrypt.update(temp.getBytes("UTF-8"));
			 byte[] numberDigest = encrypt.digest();
			 StringBuilder buf = new StringBuilder();
			 appendHexEncode(buf, numberDigest);
			 result = buf.toString();
		 } catch (Exception e) {
			 e.printStackTrace();
		 }
		 return result;
	}
	
	public static String sha256(String input){
		String result = "";
	//	byte[] array = input.getBytes();
		 try {
			 MessageDigest encrypt = MessageDigest.getInstance("SHA-256");
			 encrypt.update(input.getBytes("UTF-8"));
			 result = hexEncode(encrypt.digest());

		 } catch (Exception e) {
			 e.printStackTrace();
		 }
		 return result;
	}

	/**
	 * 轉為16進位字串
	 * @param input
	 * @return
	 */
	public static String hexEncode(byte[] input)
	{
		StringBuilder result = new StringBuilder();
		appendHexEncode(result, input);
		return result.toString();
	}
	
	/**
	 * 轉為16進位字串塞進StringBuffer
	 * @param input
	 * @param number
	 * @return
	 */
	public static void appendHexEncode(StringBuilder result, byte[] input)
	{

		for (int idx = 0; idx < input.length; ++idx)
		{
			byte b = input[idx];
			result.append(digits[(b & 0xf0) >> 4]);
			result.append(digits[b & 0x0f]);
		}
	}
	
	/**
	 * 把數字轉為16進位後，附加到StringBuffer
	 * @param sb
	 * @param num
	 */
	public static void toFullHexString(StringBuilder sb, int num) {
        char[] chs = new char[Integer.SIZE / 4];
        for(int i = 0; i < chs.length; i++) {
            chs[chs.length - 1 - i] = digits[(num >> (i * 4)) & 0xf];
        }
        sb.append(chs);
    }	
	
	/**
	 * java8才有公用的base64....
	 * @return
	 */
	public static String customBase64Encode(byte[] sourceData)
	{
		return customBase64Encode(sourceData, 0, sourceData.length);
	}
	
	/**
	 * java8才有公用的base64....
	 * @return
	 */
	public static String customBase64Encode(byte[] src, int start, int length)
	{
		//64byte 斷行一次 (PEM BASE64的標準)
		byte[] dst = new byte[(length + 2) / 3 * 4 + length / 64];
		int x = 0;
		int dstIndex = 0;
		int state = 0; // which char in pattern
		int old = 0; // previous byte
		int len = 0; // length decoded so far
		int max = length + start;
		for (int srcIndex = start; srcIndex < max; srcIndex++)
		{
			x = src[srcIndex];
			switch (++state)
			{
			case 1:
				dst[dstIndex++] = encodeData[(x >> 2) & 0x3f];
				break;
			case 2:
				dst[dstIndex++] = encodeData[((old << 4) & 0x30) | ((x >> 4) & 0xf)];
				break;
			case 3:
				dst[dstIndex++] = encodeData[((old << 2) & 0x3C) | ((x >> 6) & 0x3)];
				dst[dstIndex++] = encodeData[x & 0x3F];
				state = 0;
				break;
			}
			old = x;
			if(++len >= 64)
			{
				dst[dstIndex++] = (byte) '\n';
				len = 0;
			}
		}

		/*
		 * now clean up the end bytes
		 */

		switch (state)
		{
		case 1:
			dst[dstIndex++] = encodeData[(old << 4) & 0x30];
			dst[dstIndex++] = (byte) '=';
			dst[dstIndex++] = (byte) '=';
			break;
		case 2:
			dst[dstIndex++] = encodeData[(old << 2) & 0x3c];
			dst[dstIndex++] = (byte) '=';
			break;
		}
		return new String(dst);
	}
	
	
}
